#include "Log.hpp"
#include "Socket.hpp"
#include <iostream>
#include <memory>
#include <vector>
#include "poll.h"
using namespace Net_Work;

const static int defaultport = 8888;
const static int defaultnums = 1024;

class PollServer
{
public:
    void HandlerEvent()
    {
        for (int i = 0; i < _nums; i++)
        {
            if (_rfds[i].fd == -1)
                continue;
            if (_rfds[i].revents & POLLIN)
            {
                if (_rfds[i].fd ==_listensock->GetSocket())
                {
                    std::string clientip;
                    uint16_t clientport;
                    int sock = _listensock->AcceptConnection(&clientip, &clientport);
                    if (sock == -1)
                    {
                        lg.LogMessage(Error, "accept error\n");
                        return;
                    }
                    lg.LogMessage(Info, "客户端ip:%s 客户端端口号:%d 文件描述符:%d \n", clientip.c_str(), clientport, sock);

                    int pos = 0;
                    for (; pos < _nums; pos++)
                    {
                        if (_rfds[pos].fd == -1)
                        {
                            _rfds[pos].fd = sock;
                            _rfds[pos].events|=POLLIN;
                            lg.LogMessage(Info, "get a new link: %d\n", sock);
                            break;
                        }
                    }

                    if (pos == _nums)
                    {
                        close(_rfds[pos].fd);
                        lg.LogMessage(Warning, "select if full...\n");
                    }
                }
                else // 普通读事件就绪
                {
                    lg.LogMessage(Info, "The normal read event is ready\n");
                    std::string buffer;
                    if (recv(_rfds[i].fd, &buffer[0], buffer.size()-1,0))
                    {
                        lg.LogMessage(Info, "client say#: %s\n", buffer.c_str());
                        buffer.clear();
                    }
                    else
                    {
                        close(_rfds[i].fd);
                        _rfds[i].fd = -1;
                        _rfds[i].events = _rfds[i].revents = 0;
                    }
                }
            }
        }
    }

    PollServer(int defaultport)
        : _port(defaultport), _listensock(new TcpSocket), _isrunning(false), _nums(defaultnums)
    {}
    void InitServer()
    {
        _listensock->BuildListenSocketMethod(_port, backlog);
        _rfds = new struct pollfd[_nums];
        for (int i = 0; i < _nums; i++)
        {
            _rfds[i].fd = -1;
            _rfds[i].events = 0;
            _rfds[i].revents = 0;
        }
        _rfds[0].fd = _listensock->GetSocket();
        _rfds[0].events |= POLLIN;
    }
    void loop()
    {
        _isrunning = true;
        while (_isrunning)
        {
            PrintDebug();
            int timeout = 1000;
            int n = poll(_rfds, _nums, timeout);
            switch (n)
            {
            case 0:
                lg.LogMessage(Debug, "select timeout...,last time: %d\n", n);
                break;
            case -1:
                lg.LogMessage(Debug, "select error!!!,last time: \n");
                break;
            default:
                lg.LogMessage(Debug, "select success,begin event handler,last time: \n");
                HandlerEvent();
                break;
            }
        }
        _isrunning = false;
    }
    void stop()
    {
        _isrunning = false;
    }
    void PrintDebug()
    {
        std::cout << "current selece rfds list is : ";
        for (int i = 0; i < _nums; i++)
        {
            if (_rfds[i].fd == -1)
                continue;
            else
            {
                std::cout << _rfds[i].fd << " ";
            }
        }
        std::cout << std::endl;
    }
    ~PollServer() {
        delete[] _rfds;
    }

private:
    std::unique_ptr<Socket> _listensock;
    int _port;
    int _isrunning;
    int _nums;
    struct pollfd *_rfds;
};